68장. DynamoDB의 용량 모델과 비용
이 장에서 말하고자 하는 것
DynamoDB는 “초당 얼마나 처리할 수 있는지” 를 두 가지 모델로 다룬다.
- On-Demand (PAY_PER_REQUEST)
- Provisioned
이 선택이 비용과 운영 성격을 결정한다.
1. On-Demand — 가장 단순
요청한 만큼 자동 처리
사용한 만큼 청구
- 트래픽을 미리 예측할 필요 없다
- 폭증 트래픽에도 자동 대응
- 단위 비용은 Provisioned 보다 비쌈
새 프로젝트는 거의 항상 On-Demand로 시작한다.
2. Provisioned — 미리 정해두기
RCU (Read Capacity Unit) : 초당 읽기 단위
WCU (Write Capacity Unit) : 초당 쓰기 단위
미리 RCU · WCU를 잡아두고 그 안에서 처리한다.
- 단위 비용이 싸다
- 정해진 한도를 넘으면 throttle (요청 거부)
- Auto Scaling으로 동적 조정 가능
트래픽이 일정하거나 충분히 예측되는 운영 환경에서만 권장
3. RCU · WCU 의 의미
대략적인 단위.
1 RCU = 초당 4KB 이하 항목 1번 강한 일관성 읽기
또는 초당 4KB 이하 항목 2번 결과적 일관성 읽기
1 WCU = 초당 1KB 이하 항목 1번 쓰기
큰 항목은 더 많은 단위를 잡아먹는다.
항목을 작게 유지하면 비용이 직접적으로 줄어든다
4. Throttle — 한도를 넘었을 때
Provisioned에서 RCU/WCU를 넘으면 ProvisionedThroughputExceededException 으로 거부된다.
이 시점에 일부 요청이 실패한다
클라이언트는 지수 백오프 (Exponential Backoff) 로 재시도.
운영 알람: throttle 발생 시 즉시 알람
5. Hot Partition과 처리량
DynamoDB는 처리량을 파티션마다 나눠 가진다.
전체 1,000 WCU
파티션 10개 → 한 파티션당 100 WCU
한 파티션 키에 트래픽이 몰리면 그 100 WCU를 넘는 순간 throttle.
카디널리티 높은 파티션 키가 결정적으로 중요한 이유
6. 비용을 가르는 항목
DynamoDB 청구서의 주요 항목:
- RCU/WCU (또는 On-Demand 요청 수)
- 스토리지
- 백업 (PITR + 스냅샷)
- GSI · LSI (별도 청구)
- DynamoDB Streams (이벤트 스트림 켤 때)
- Global Table (멀티 리전 복제)
7. 비용 절감 패턴
1. TTL (Time To Live)
만료 시각이 있는 데이터는 자동 삭제.
세션 토큰: 1시간 후 삭제
캐시 항목: 24시간 후 삭제
aws dynamodb update-time-to-live \
--table-name sessions \
--time-to-live-specification "Enabled=true,AttributeName=expires_at"
TTL은 무료다. 안 쓸 이유가 거의 없다
2. 항목 크기 줄이기
긴 필드명을 짧게.
"customer_email" → "ce"
서비스 코드에 매핑 레이어를 두고 저장 형식만 짧게 한다.
3. Eventual Consistency 활용
가능한 곳은 결과적 일관성으로 → RCU 절반.
4. On-Demand → Provisioned 전환
트래픽이 안정되면 Provisioned + Auto Scaling 으로 옮긴다.
8. 우리 서비스에서
[Table "sessions"]
- On-Demand
- TTL on expires_at (1시간 후 삭제)
[Table "products"]
- On-Demand 시작
- 트래픽 안정되면 Provisioned + Auto Scaling
[Table "events"]
- On-Demand
- TTL on expires_at (90일 후 삭제)
세션 · 이벤트 같은 짧게 사는 데이터에 TTL을 거는 게 큰 절감.
9. 직접 확인해보기 — CLI
Provisioned 로 변경
aws dynamodb update-table \
--table-name orders \
--billing-mode PROVISIONED \
--provisioned-throughput ReadCapacityUnits=10,WriteCapacityUnits=10
Auto Scaling 등록
aws application-autoscaling register-scalable-target \
--service-namespace dynamodb \
--resource-id "table/orders" \
--scalable-dimension dynamodb:table:WriteCapacityUnits \
--min-capacity 5 \
--max-capacity 100
Throttle 메트릭
aws cloudwatch get-metric-statistics \
--namespace AWS/DynamoDB \
--metric-name ThrottledRequests \
--dimensions Name=TableName,Value=orders \
--start-time 2026-01-01T00:00:00Z \
--end-time 2026-01-02T00:00:00Z \
--period 60 \
--statistics Sum
10. 코드로는 이렇게 생겼다 — Terraform
resource "aws_dynamodb_table" "sessions" {
name = "sessions"
billing_mode = "PAY_PER_REQUEST"
hash_key = "session_id"
attribute {
name = "session_id"
type = "S"
}
ttl {
enabled = true
attribute_name = "expires_at"
}
point_in_time_recovery {
enabled = true
}
}
ttl 한 블록이 큰 비용 절감을 만든다.
11. 이렇게 쓰면 망한다 — 안티패턴
안티패턴 1. 처음부터 Provisioned로 시작한다
트래픽 예측이 어렵다. throttle로 사고난다.
시작은 On-Demand → 안정 후 Provisioned
안티패턴 2. TTL을 안 켠다
세션 · 캐시 · 임시 데이터가 영원히 쌓인다.
안티패턴 3. 항목 하나에 거대한 페이로드를 박는다
1 WCU = 1KB. 100KB 항목 = 100 WCU.
큰 데이터는 S3로 → DynamoDB에는 메타만
안티패턴 4. throttle 알람 없이 운영
요청이 거부되는데도 모른다.
12. 한 줄로 정리
DynamoDB 비용은 처리량 모델 + 항목 크기 + 인덱스 + TTL 로 결정되며,
시작은 On-Demand + TTL 이 거의 항상 정답이다
13. 이 장의 핵심 정리
- 처리량 모델은 On-Demand · Provisioned 두 가지다.
- 새 프로젝트는 On-Demand로 시작한다.
- RCU/WCU 단위로 비용이 매겨진다 — 항목 크기가 직접적인 영향.
- Hot Partition은 처리량 한도를 결정적으로 끌어내린다.
- TTL · 항목 크기 줄이기 · Eventual Consistency 가 비용 절감의 세 축.
- throttle 알람은 운영 기본값.